#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <time.h>


#define SERVER_TCP_PORT 25045 
#define SIZE 512

int sigflag;

int resquiescat(){wait();sigflag = 1;} /*called by SIGCHLD event handler*/

int err_stop (char* msg)
{
	printf("%s \n",msg);
	//exit(-1);
}


int main(int argc, char*argv[ ]) 
{
	
	int sdw,sd2,childpid;

 	int sockfd, clilen,n;
 	
 	/* Prepare acknowledging child termination */
    sigset(SIGCHLD, resquiescat);

 	struct sockaddr_in serv_addr, cli_addr;  /*we assume this responder is a server and the intiator is a client*/
 	/* message size*/
 	char msg[SIZE];
	char*aurevoir = (char*) malloc (sizeof(char)*20);
	time_t rawtime;

  	// Open a TCP socket (an Internet streams socket) 
	if ( (sdw = socket (PF_INET, SOCK_STREAM, 0)) < 0){
     	 	err_stop ("server: can't open TCP socket");  //we assume this performs perror() and exit(-1)
		exit(-1);
	}
	
	//Bind our local address so that the client can send to  us

       bzero((char *) &serv_addr, sizeof(serv_addr));
       serv_addr.sin_family      = AF_INET;
       serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
       serv_addr.sin_port        = htons(SERVER_TCP_PORT);


       if (bind(sdw, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0){
		err_stop ("server: can't bind local address");
		exit(-1);	
       }

      /*set up queue for connection request */

	
	//print server port and IP address
	//inet_ntoa convert the server address into a string 
	printf("SERVER ADDRESS : %s \n", (char*)inet_ntoa(serv_addr));
	printf("SERVER PORT : %d \n", SERVER_TCP_PORT);
	
	
	sprintf(aurevoir ,"%s ","Au revoir"); 


	// Set de maximum number of pending requests
	 if(listen(sdw,5)<0){
         	err_stop("listen error : Server queue full ");
         	exit(-1);
	 }

	
	
	for(;;){
		sigflag = 0;
	     	
		/* Wait for a connection from a client processes.
                 * This is an example of a concurrent server. */
                 
          	/* Wait for a connection from a client processes.
           	 */
		clilen = sizeof(cli_addr); 
		if ((sd2 = accept(sdw, (struct sockaddr *) &cli_addr, &clilen)) > 0){

			char *clienthost;
			int cli_port;
			
			clienthost = (char*)inet_ntoa(cli_addr.sin_addr);
        		cli_port = ntohs(cli_addr.sin_port);
        		printf("[Info] : Requete en provenance de l'hoste [%s] dont le port est [%d] \n",clienthost, cli_port);			

			/*Accept request from all network interfaces of any machine 
                         *(each network interface has a separate IP address) */
			{ 
            			if(sigflag == 1)continue; 

                   		/*just in case we get SIGCHLD during accept*/                                      
             			//perror("accept error in server");
             			//exit(-1);
          	}

			if((childpid = fork()) < 0){

             		perror("fork error in telnetd");
             		exit(-1);
          	}

          		else if (childpid == 0){
				//Le processus fils ferme la socket dont il n'a pas besoin
             			close(sdw);
                		if((n = recv (sd2, msg,SIZE,0)) > 0){
						msg[n] = '\0';	
						printf("%s \n",msg);
						//time_t rawtime;				
						int compteurs = 0;
						//int msglength = strlen(msg);				
						for(compteurs = 0; compteurs <60 ;compteurs++){
							char response[SIZE];
							struct tm * ptm;
							time (&rawtime);					
							ptm = localtime (&rawtime);							
							sprintf(response,"Il est %d : %d :%d ! \n",ptm->tm_hour,ptm->tm_min,ptm->tm_sec); 
							int t;
							if( t = (send (sd2, response,strlen(response),0)) < 0){
								err_stop ("server: send error");
								close(sd2);
							} 
							//Le pere dors pendant une seconde
							sleep(1);				
						}
				
					if(compteurs = (send (sd2,aurevoir,strlen(aurevoir),0)) < 0){
						err_stop ("server: send error");
						close(sd2);
					}					
					//Le processus fils a fini ; il ferme donc le socket		
					close(sd2);        	
					}
					else{
						 err_stop("server: an error occur when receiving the message");
						 close(sd2);
					} 
					printf("[Info] : Fin de service du client en provenance de l'hoste [%s] dont le port est [%d] \n",clienthost, cli_port);	
             				exit(0);
          			}//fin du processus fils 
        		//le processus pere ferme le socket dont il n'a pas besoin
         		close(sd2); 

			
          	}
	
	}	
	exit(0);
	
}




